package com.sakura.mall.generator.service.impl;

import com.sakura.mall.generator.config.GeneratorConfig;
import com.sakura.mall.generator.model.ColumnInfo;
import com.sakura.mall.generator.model.TableInfo;
import com.sakura.mall.generator.service.DatabaseService;
import com.sakura.mall.generator.util.StringUtils;
import com.sakura.mall.generator.util.TypeConverter;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * MySQL数据库服务实现
 */
@Service
@RequiredArgsConstructor
public class MySqlDatabaseServiceImpl implements DatabaseService {

    private final GeneratorConfig config;
    private final DataSource dataSource;
    
    /**
     * 获取数据库连接
     */
    private Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
    
    @Override
    public List<TableInfo> getAllTables() {
        List<TableInfo> tableInfos = new ArrayList<>();
        List<String> tableNames = getAllTableNames();
        
        for (String tableName : tableNames) {
            TableInfo tableInfo = getTableInfo(tableName);
            if (tableInfo != null) {
                tableInfos.add(tableInfo);
            }
        }
        
        return tableInfos;
    }
    
    @Override
    public TableInfo getTableInfo(String tableName) {
        try (Connection connection = getConnection()) {
            TableInfo tableInfo = new TableInfo();
            tableInfo.setTableName(tableName);
            
            // 获取表注释
            DatabaseMetaData metaData = connection.getMetaData();
            ResultSet resultSet = metaData.getTables(connection.getCatalog(), null, tableName, new String[]{"TABLE"});
            if (resultSet.next()) {
                tableInfo.setTableComment(resultSet.getString("REMARKS"));
            }
            
            // 设置列信息
            List<ColumnInfo> columns = getTableColumns(tableName);
            ColumnInfo primaryKey = getPrimaryKey(tableName);
            
            tableInfo.setPrimaryKey(primaryKey);
            tableInfo.setColumns(columns);
            
            // 设置类名和包名
            String tableNameWithoutPrefix = StringUtils.removePrefix(tableName, config.getTablePrefix());
            tableInfo.setUpperCamelName(StringUtils.toPascalCase(tableNameWithoutPrefix));
            tableInfo.setLowerCamelName(StringUtils.toCamelCase(tableNameWithoutPrefix));
            tableInfo.setPackageName(config.getPackageName() + (config.getModuleName() != null ? "." + config.getModuleName() : ""));
            
            return tableInfo;
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }
    
    @Override
    public List<ColumnInfo> getTableColumns(String tableName) {
        List<ColumnInfo> columns = new ArrayList<>();
        try (Connection connection = getConnection()) {
            DatabaseMetaData metaData = connection.getMetaData();
            ResultSet resultSet = metaData.getColumns(connection.getCatalog(), null, tableName, null);
            
            ColumnInfo primaryKey = getPrimaryKey(tableName);
            
            while (resultSet.next()) {
                String columnName = resultSet.getString("COLUMN_NAME");
                
                // 跳过主键，主键单独处理
                if (primaryKey != null && columnName.equals(primaryKey.getColumnName())) {
                    continue;
                }
                
                ColumnInfo columnInfo = new ColumnInfo();
                columnInfo.setColumnName(columnName);
                columnInfo.setDataType(resultSet.getString("TYPE_NAME"));
                columnInfo.setColumnComment(resultSet.getString("REMARKS"));
                columnInfo.setNullable(resultSet.getInt("NULLABLE") == DatabaseMetaData.columnNullable);
                columnInfo.setColumnSize(resultSet.getInt("COLUMN_SIZE"));
                columnInfo.setPrimaryKeyFlag(false);
                columnInfo.setAutoIncreaseFlag(false);
                
                // 设置Java属性名和类型
                columnInfo.setFieldName(StringUtils.toCamelCase(columnName));
                columnInfo.setJavaType(TypeConverter.convertToJavaType(columnInfo.getDataType()));
                
                // 设置字段展示标志
                columnInfo.setFormFlag(true); // 默认所有字段都显示在表单中
                
                // 只有字符串类型的字段作为查询条件
                String javaType = columnInfo.getJavaType();
                columnInfo.setQueryFlag("String".equals(javaType));
                
                // 默认所有字段都显示在列表中
                columnInfo.setListFlag(true);
                
                // 如果字段非空，设置必填标志
                if (!columnInfo.isNullable()) {
                    columnInfo.setRequiredFlag(true);
                }
                
                columns.add(columnInfo);
            }
            
            return columns;
        } catch (SQLException e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
    }
    
    @Override
    public ColumnInfo getPrimaryKey(String tableName) {
        try (Connection connection = getConnection()) {
            DatabaseMetaData metaData = connection.getMetaData();
            ResultSet primaryKeys = metaData.getPrimaryKeys(connection.getCatalog(), null, tableName);
            
            if (primaryKeys.next()) {
                String pkColumnName = primaryKeys.getString("COLUMN_NAME");
                ColumnInfo primaryKey = new ColumnInfo();
                primaryKey.setColumnName(pkColumnName);
                primaryKey.setPrimaryKeyFlag(true);
                
                // 获取主键的其他信息
                ResultSet columns = metaData.getColumns(connection.getCatalog(), null, tableName, pkColumnName);
                if (columns.next()) {
                    primaryKey.setDataType(columns.getString("TYPE_NAME"));
                    primaryKey.setColumnComment(columns.getString("REMARKS"));
                    primaryKey.setNullable(false); // 主键不能为空
                    primaryKey.setColumnSize(columns.getInt("COLUMN_SIZE"));
                    
                    // MySQL中自增判断
                    String isAutoincrement = columns.getString("IS_AUTOINCREMENT");
                    primaryKey.setAutoIncreaseFlag("YES".equals(isAutoincrement));
                    
                    // 设置Java属性名和类型
                    primaryKey.setFieldName(StringUtils.toCamelCase(pkColumnName));
                    primaryKey.setJavaType(TypeConverter.convertToJavaType(primaryKey.getDataType()));
                    
                    // 设置主键的表单和列表标志
                    primaryKey.setFormFlag(false); // 主键通常不在表单中显示
                    primaryKey.setQueryFlag(false); // 主键通常不作为查询条件
                    primaryKey.setListFlag(true);  // 主键通常显示在列表中
                    primaryKey.setRequiredFlag(false); // 主键通常由系统生成
                }
                
                return primaryKey;
            }
            
            return null;
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }
    
    @Override
    public List<String> getAllTableNames() {
        List<String> tableNames = new ArrayList<>();
        try (Connection connection = getConnection()) {
            DatabaseMetaData metaData = connection.getMetaData();
            ResultSet tables = metaData.getTables(connection.getCatalog(), null, null, new String[]{"TABLE"});
            
            while (tables.next()) {
                String tableName = tables.getString("TABLE_NAME");
                // 排除系统表
                if (!tableName.startsWith("sys_") && !tableName.startsWith("information_schema")) {
                    tableNames.add(tableName);
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return tableNames;
    }
} 